<?php
/*
 * @Description    : 验证码
 * @Author         : QianLong
 * @Date           : 2022-10-08 20:53:52
 * @LastEditors    : QianLong
 * @Site           : http://www.21ds.cn
 * @LastEditTime   : 2024-01-16 17:03:55
 */

namespace App\Service;

use App\Common\RedisCache;
use App\Exception\ApiException;
use App\Service\Captcha\TencBase;
use Yurun\Util\HttpRequest;

class Captcha
{
    protected $config;
    protected $http;
    public function __construct($config)
    {
        $this->config = $config;
        $this->http = new HttpRequest;
        if (isset($this->config['ak_from']) && $this->config['ak_from'] == 'platform' && isset($this->config['ak_id']) && !empty($this->config['ak_id'])) {
            $akInfo = (new RedisCache)->getAk($this->config['ak_id'], $this->config['uid']);
            unset($akInfo['_id']);
            $this->config = array_merge($this->config, $akInfo);
            unset($akInfo);
        }
    }
    public function tencentCheck($token, $ip)
    {
        $paramsInput = base64_decode($token);
        $paramsInput = html_entity_decode($paramsInput);
        $paramsInput = json_decode($paramsInput, true);
        // 进行在线验证
        $host   = 'captcha.tencentcloudapi.com';
        $params = [
            'CaptchaType'  => 9,
            'Ticket'       => $paramsInput['ticket'],
            'UserIp'       => $ip,
            'Randstr'      => $paramsInput['randstr'],
            'CaptchaAppId' => (int)$this->config['tenc_app_id'],
            'AppSecretKey' => $this->config['tenc_app_secret']
        ];

        $result = (new TencBase($this->config))->curl_post($host, $params, 'DescribeCaptchaResult', 'captcha', '2019-07-22');
        $file = BASE_PATH . '/runtime/tencent_captcha.txt';
    file_put_contents($file, $result);
        $result = json_decode($result, true);
        if (isset($result['Response']['Error']['Code'])) {
            throw new ApiException(-1, $result['Response']['Error']['Code'] . '; [Message：' . $result['Response']['Error']['Message'] . ']');
        }
        if (isset($result['Response']['CaptchaCode']) && $result['Response']['CaptchaCode'] != 1) {
            throw new ApiException(-1, $result['Response']['CaptchaMsg']);
        }
    }
    public function geetestCheck($token)
    {
        $url = 'http://gcaptcha4.geetest.com/validate';
        $reqPost = base64_decode($token);
        $reqPost = html_entity_decode($reqPost);
        $reqPost = json_decode($reqPost, true);
        $reqPost['sign_token'] = hash_hmac('sha256', $reqPost['lot_number'], $this->config['geetest_key']);
        $resultObj = $this->http->post($url, $reqPost);
        $result = json_decode($resultObj->body(), true);
        if (isset($result['status']) && $result['status'] == 'error') {
            throw new ApiException(-1, $result['msg']);
        }
        if ($result['result'] != 'success') {
            throw new ApiException(-1, $result['reason']);
        }
    }
    public function aliyunCheck($token, $ip)
    {
        $reqPost = json_decode(html_entity_decode(base64_decode($token)), true);
        $paramData['Action'] = 'AuthenticateSig';
        $paramData['Format'] = 'JSON';
        $paramData['Version'] = '2018-01-12';
        $paramData['SignatureMethod'] = 'HMAC-SHA1';
        $paramData['SignatureNonce'] = createULId();
        $paramData['SignatureVersion'] = '1.0';
        $paramData['AccessKeyId'] = $this->config['aliyun_key_id'];
        $paramData['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
        $paramData['Token'] = $reqPost['nc_token'];
        $paramData['Sig'] = $reqPost['sig'];
        $paramData['SessionId'] = $reqPost['csessionid'];
        $paramData['Scene'] = $reqPost['scene'];
        $paramData['AppKey'] = $this->config['aliyun_captcha_key'];
        $paramData['RemoteIp'] = $ip;
        $sign_str = 'GET&/&' . http_build_query($paramData);
        $paramData['Signature'] = base64_encode(hash_hmac('sha1', urlencode($sign_str), $this->config['aliyun_key_secret'] . '&', true));
        $url = 'https://afs.aliyuncs.com/?' . http_build_query($paramData);
        $resultObj = $this->http->get($url);
        $result = json_decode($resultObj->body(), true);
        if (isset($result['Code']) && $result['Code'] != 100) {
            throw new ApiException(-1, $result['Msg']);
        }
        // if ($result['success'] != true) {
        //     throw new ApiException(-1, $result['Msg']);
        // }
    }
    public function getJdSessionId($params)
    {
        $jdCloud = new JDCloud($this->config, true);
        $result = $jdCloud->doRequest('https://captcha.jdcloud-api.com/v1/captcha:getsessionid', 'POST', 'captcha', 'cn-north-1', $params);
        if (empty($result)) {
            return 'passed';
        }
        if (!isset($result['result']['data']['code']) || $result['result']['data']['code'] == '0002' || $result['result']['data']['code'] == '0000' || $result['result']['data']['code'] == '0001') {
            return 'passed';
        }
        return $result['result']['data']['sessionId'];
    }
    public function verifyJdToken($params)
    {
        $paramsInput = base64_decode($params['token']);
        $paramsInput = html_entity_decode($paramsInput);
        $paramsInput = json_decode($paramsInput, true);
        $jdPost['verifyToken'] = $paramsInput['vt'];
        $jdPost['sessionId'] = $paramsInput['ssd'];
        $jdPost['appId'] = (int)$this->config['jdcloud_app_id'];
        $jdPost['sceneId'] = (int)$this->config['jdcloud_scene_id'];
        $jdPost['secret'] = $this->config['jdcloud_scene_secret'];
        $jdPost['ip'] = $params['ip'];
        $jdPost['userAgent'] = $params['userAgent'];
        $jdPost['clientType'] = $this->config['jdcloud_client_type'];
        $jdCloud = new JDCloud($this->config, true);
        $result = $jdCloud->doRequest('https://captcha.jdcloud-api.com/v1/captcha:verifytoken', 'POST', 'captcha', 'cn-north-1', $jdPost);
        if (!empty($result) && isset($result['result']['data']['code']) && $result['result']['data']['code'] != '0000') {
            throw new ApiException(-1, json_encode($result, JSON_UNESCAPED_UNICODE));
        }
    }
}
